package com.fuhe.chen.vendingmachine.controller;

import com.fuhe.chen.vendingmachine.alipay.Alipay;
import com.fuhe.chen.vendingmachine.common.MachineCache;
import com.fuhe.chen.vendingmachine.constant.MessageConstant;
import com.fuhe.chen.vendingmachine.dto.ApiResponse;
import com.fuhe.chen.vendingmachine.dto.ApiResponseForList;
import com.fuhe.chen.vendingmachine.common.redis.RedisUtils;
import com.fuhe.chen.vendingmachine.common.Utils;
import com.fuhe.chen.vendingmachine.dto.ItemInMachine;
import com.fuhe.chen.vendingmachine.pojo.*;
import com.fuhe.chen.vendingmachine.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.*;

@Controller
@Api(tags = "支付接口(面向售货机平板)")
public class HomeController {

    private static final Logger LOGGER = LoggerFactory.getLogger(HomeController.class);

    @Autowired
    IMachineService machineService;

    @Autowired
    ICommodityService commodityService;

    @Autowired
    IOrderService orderService;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    IBookOrderService bookOrderService;

    @Autowired
    IMQTTService imqttService;

    @Autowired
    IItemService itemService;

    /**
     * 用户网页商城购买动作
     *
     * @return
     */
    @ApiOperation("生成支付宝支付网页")
    @GetMapping("Api/Web/AliPay/{BookOrderId}")
    @ResponseBody
    public ApiResponse<String> buy(@PathVariable("BookOrderId") String BookOrderId) {
        ApiResponse<String> response = new ApiResponse<>();

        BookOrder bookOrder = bookOrderService.queryOrderByOrderId(BookOrderId);


        if (bookOrder == null) {
            response.setSuccess(false);
            response.setCode(MessageConstant.Error.INVALID_PARAM_CODE);
            response.setMessage("调用失败");
            response.setData(MessageConstant.BookOrder.NO_SUCH_ORDER_ID);

            return response;
        }

        String orderPrice = String.valueOf(String.format("%.2f", bookOrder.getAmount()));
        String commodityName = "富禾售货机";
        String body = "预约单商品";


        response.setSuccess(true);
        response.setCode(10000);
        response.setMessage("调用成功");
        response.setData(Alipay.doPay(bookOrder.getId(), orderPrice, commodityName, body));

        return response;
    }

    /**
     * 用户购买动作
     * 生成待支付订单
     * 返回支付链接
     *
     * @return
     */
    @ApiOperation("生成订单并获取支付二维码字符串")
    @GetMapping("Api/Phone/PreCreatePay/{machineId}/{ItemIdInMachine}")
    @ResponseBody
    public ApiResponseForList<String> buy2(@PathVariable("ItemIdInMachine") String ItemIdInMachine,
                                           @PathVariable("machineId") String machineId) {
        List<Integer> itemAttr = new ArrayList<>();
        Float price = 0F;
        String[] split = ItemIdInMachine.split(",");
        for (String s : split) {
            itemAttr.add(Integer.valueOf(s));
        }
        System.out.println(itemAttr.toString());
        Map<ItemInMachine, Integer> itemMap = new HashMap<ItemInMachine, Integer>();

        for (Integer attr : itemAttr) {
            ItemInMachine item = itemService.queryItem(attr);
            itemMap.put(item, 1);
            price = price + item.getPrice();
        }

        //自动生成订单号
        String tradeNo = Utils.getOrderIdByTime();


        //添加待支付订单
        Order order = new Order();
        order.setId(tradeNo);
        order.setOrderName(tradeNo);
        order.setAmount(String.format("%.2f", price));
        order.setOrderStatus(0);  //0--待支付
        order.setCreateDate(new Date().getTime());
        order.setMachineId(Integer.valueOf(machineId));
        Machine machine = machineService.findOne(Integer.valueOf(machineId));
        order.setPlace(machine.getPlace());
        orderService.addOrder(order);

        //此处向缓存中添加已售商品信息
        commodityService.addCommoditySoldToCache(tradeNo, itemMap, machineId);

        String orderPrice = String.valueOf(String.format("%.2f", price));
        String commodityName = "贩卖机商品";
        String body = "贩卖机商品";

        ApiResponseForList<String> response = new ApiResponseForList<>();
        List<String> list = new ArrayList<>();
        response.setSuccess(true);
        response.setCode(10000);
        response.setMessage("调用成功");
        list.add(Alipay.PreCreatePay(tradeNo, orderPrice, commodityName, body, machineId));
        response.setData(list);

        //向支付宝提供订单信息并获取支付二维码字符串
        return response;
    }

    /**
     * 接收支付宝回调方法
     *
     * @param request
     * @param response
     */
    @RequestMapping("/getNotify")
    public void getNotify(HttpServletRequest request, HttpServletResponse response) {

        //支付宝验签
        boolean flag = Alipay.checkSign(request);

        if (flag) {
            try {
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
                //支付时间
                String payDate = new String(request.getParameter("gmt_payment").getBytes("ISO-8859-1"), "UTF-8");
                //购买者支付宝id
                String buyer_id = new String(request.getParameter("buyer_id").getBytes("ISO-8859-1"), "UTF-8");

                //此处向下位机发送操作指令,将商品拿出
                imqttService.sendMessageForPurchase(out_trade_no);

                //订单成功处理
                orderService.orderToSuccess(out_trade_no, trade_no, payDate, buyer_id);

                //将机器剩余容量加1
                BookOrder bookOrder = bookOrderService.queryOrderByOrderId(out_trade_no);
                MachineCache.addCapacity(bookOrder.getMachine_id());

                //向支付宝返回success，如果不做支付宝会在24小时内再次发送6-10次回调
                PrintWriter writer = null;
                writer = response.getWriter();
                writer.write("success"); // 一定要打印success
                writer.flush();
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            //订单未通过
        }
    }

    /**
     * 接收支付宝回调方法
     *
     * @param request
     * @param response
     */
    @ApiOperation("接收支付宝回调方法")
    @RequestMapping("/getAppNotify")
    public void getAppNotify(HttpServletRequest request, HttpServletResponse response) {

        //支付宝验签
        boolean flag = Alipay.checkSign(request);

        if (flag) {
            try {
                //商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"), "UTF-8");
                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"), "UTF-8");
                //支付时间
                String payDate = new String(request.getParameter("gmt_payment").getBytes("ISO-8859-1"), "UTF-8");
                //购买者支付宝id
                String buyer_id = new String(request.getParameter("buyer_id").getBytes("ISO-8859-1"), "UTF-8");

                //预约订单支付成功处理
                bookOrderService.payBookOrder(out_trade_no, 0, buyer_id, trade_no);

                //将机器剩余容量减1
                BookOrder bookOrder = bookOrderService.queryOrderByOrderId(out_trade_no);
                MachineCache.reduceCapacity(bookOrder.getMachine_id());

                // 向支付宝返回success，如果不做支付宝会在24小时内再次发送6-10次回调
                PrintWriter writer = null;
                writer = response.getWriter();
                writer.write("success"); // 一定要打印success
                writer.flush();
                return;
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            //订单未通过
        }
    }

    /**
     * 接收微信验证方法
     * @param request
     * @param response
     */
    @ApiOperation("接收支付宝回调方法")
    @GetMapping("/weChatCheck")
    @ResponseBody
    public String weChatCheck(HttpServletRequest request, HttpServletResponse response) {
        String signature = request.getParameter("signature");
        String timestamp = request.getParameter("timestamp");
        String nonce = request.getParameter("nonce");
        String token = "wechat";
        String echostr = request.getParameter("echostr");

        System.out.println(signature);
        System.out.println(timestamp);
        System.out.println(nonce);
        System.out.println(echostr);


        List<String> arr = new ArrayList<>();
        arr.add(token);
        arr.add(timestamp);
        arr.add(nonce);
        Collections.sort(arr, new Comparator<String>() {
            public int compare(String o1, String o2) {
                try {
                    // 取得比较对象的汉字编码，并将其转换成字符串
                    String s1 = new String(o1.toString().getBytes("GB2312"), "ISO-8859-1");
                    String s2 = new String(o2.toString().getBytes("GB2312"), "ISO-8859-1");
                    // 运用String类的 compareTo（）方法对两对象进行比较
                    return s1.compareTo(s2);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return 0;
            }
        });// 根据元素的自然顺序 对指定列表按升序进行排序。

        StringBuilder tempB = new StringBuilder();
        for (String s : arr) {
            tempB.append(s);
        }
        String temp = tempB.toString();
        temp = shaEncode(temp);

        System.out.println(temp);

        if(temp.equals(signature)){
            return echostr;
        }



        return null;
    }

    private static String shaEncode(String inStr) {
        MessageDigest sha = null;
        try {
            sha = MessageDigest.getInstance("SHA");
        } catch (Exception e) {
            System.out.println(e.toString());
            e.printStackTrace();
            return "";
        }

        byte[] byteArray = new byte[0];
        try {
            byteArray = inStr.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] md5Bytes = sha.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
}
